/*
 * Copyright 2011 Daniel Drown
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * interfaces.c - calculate the local CLAT subnet based on the gprs interface
 */
#include "system_headers.h"
#include "interfaces.h"
#include "config.h"

struct in6_addr ipv6_local_subnet;

/* function: set_local_ipv6_prefix
 * calculate the local CLAT subnet based on the gprs interface
 */
void set_local_ipv6_prefix() {
  struct ifaddrs *local_interfaces, *an_interface;
  struct sockaddr_in6 *interface_address;
#ifdef DEBUG_PRINT
  char charbuffer[INET6_ADDRSTRLEN];
#endif

  if(getifaddrs(&local_interfaces) < 0) {
    perror("getifaddrs");
    exit(1);
  }

  for(an_interface = local_interfaces; an_interface; an_interface = an_interface->ifa_next) {
    if(
	(strcmp(an_interface->ifa_name, GPRS_INTERFACE) == 0) && 
	an_interface->ifa_addr && 
	(an_interface->ifa_addr->sa_family == AF_INET6) && 
	(an_interface->ifa_flags & IFF_UP)
	) {
      interface_address = (struct sockaddr_in6 *)an_interface->ifa_addr;

      if(interface_address->sin6_scope_id == 0) { // only if it's a global address
	ipv6_local_subnet = interface_address->sin6_addr;
	ipv6_local_subnet.s6_addr32[2] = IPV6_SUBNET_2;
	ipv6_local_subnet.s6_addr32[3] = IPV6_SUBNET_3;

#ifdef DEBUG_PRINT
	printf("local ipv6 addr = %s\n",inet_ntop(AF_INET6, &ipv6_local_subnet, charbuffer, sizeof(charbuffer)));
#endif

	freeifaddrs(local_interfaces);
	return;
      }
    }
  }
  
  printf("no ipv6 " GPRS_INTERFACE " interface detected\n");
  exit(1);
}
